/**
 * 修改记录:
 * 25-09-11     郑朝军
 */

/**
 * uni.cxapp.FieldControl
 * ZGIS-字段控制相关方法
 *
 * @class
 * @memberof    uni.cxapp.FieldControl
 */
export default
{
    methods:
    {
      /**
       * 通知组件刷新
       * @param {string|null} editingColName 正在编辑的字段名
       * @param {boolean} makeCode 是否生成编码
       */
      notifyChanged(editingColName = null, makeCode = true)
      {
        this.editingColName = editingColName

        if (makeCode)
        {
          this.makeCode()
        }

        // 触发响应式更新
        this.$forceUpdate()

        // 触发变化事件
        this.$emit('notify-changed', this.internalAttMap, editingColName)   
      },

      /**
       * 获取某个字段的字典值集合
       * @param {string} colName 字段名
       * @returns {Array} 字典值列表
       */
      getFldValues(colName)
      {
        return this.fldValueMap[colName] || []
      },

      /**
       * 设置某个字段的字典值
       * @param {string} colName 字段名
       * @param {Array} list 字典值列表
       */
      setFldValues(colName, list)
      {
        this.$set(this.fldValueMap, colName, list)
        this.notifyChanged(colName, false)
      },

      /**
       * 禁用某个字段
       * @param {string} colName 字段名
       */
      disableCol(colName)
      {
        const fld = this.internalFldList.find(f => f.colname === colName)
        if (fld)
        {
          fld.newedit = 0
          fld.editable = 0
          this.notifyChanged(colName, false)
        }
      },

      /**
       * 启用某个字段
       * @param {string} colName 字段名
       */
      enableCol(colName)
      {
        const fld = this.internalFldList.find(f => f.colname === colName)
        if (fld?.editable === 0)
        {
          fld.newedit = 1
          fld.editable = 1
          this.notifyChanged(colName, false)
        }
      },

      /**
       * 隐藏某个字段（支持多个，使用","分割）
       * @param {string} colNames 要隐藏的字段名
       */
      hideCol(colNames)
      {
        const cols = colNames.split(',')

        for (const fld of this.internalFldList)
        {
          if (cols.includes(fld.colname))
          {
            fld.disporder = 0

            if (cols.length === 1)
            {
              break
            }
          }
        }

        this.notifyChanged(null, false)
      },

      /**
       * 显示某个隐藏的字段（支持多个，使用","分割）
       * @param {string} colNames 要显示的字段名
       * @param {number|null} disPOrder 显示位置，默认为字段原始位置
       */
      showCol(colNames, disPOrder = null)
      {
        const cols = colNames.split(',')

        for (const fld of this.internalFldList)
        {
          if (cols.includes(fld.colname))
          {
            fld.disporder = disPOrder || fld.tempOrder || 1

            if (cols.length === 1)
            {
              break
            }
          }
        }

        this.notifyChanged(null, false)
      },

      /**
       * 设置字段是否可为空
       * @param {string} colName 字段名
       * @param {boolean} nullable 是否可为空
       */
      setNullable(colName, nullable)
      {
        const fld = this.internalFldList.find(f => f.colname === colName)
        if (fld)
        {
          fld.nullable = nullable ? 1 : 0

          // 更新验证规则
          this.updateFieldRule(colName, fld)
          this.notifyChanged(colName, false)
        }
      },

      /**
       * 更新字段验证规则
       * @param {string} colName 字段名
       * @param {Object} fld 字段对象
       */
      updateFieldRule(colName, fld)
      {
        const rules = [...(this.formRules[colName] || [])]

        // 移除旧的必填规则
        const requiredIndex = rules.findIndex(rule => rule.required)
        if (requiredIndex !== -1)
        {
          rules.splice(requiredIndex, 1)
        }

        // 添加新的必填规则
        if (fld.nullable === 0)
        {
          rules.unshift({
              required: true,
              message: `${fld.namec}不能为空`,
              trigger: 'submit'
          })
        }

        this.$set(this.formRules, colName, rules)
      },

      /**
       * 改变表单状态
       * @param {number} mode 新的表单模式 7-添加，5-修改，6-查询
       */
      changeMode(mode)
      {
        this.internalMode = mode

        // 重新处理字段可编辑性
        this.processFieldVisibility()

        // 触发状态变化事件
        this.$emit('mode-changed', mode)

        this.notifyChanged(null, false)
      },

      /**
       * 处理字段可见性
       */
      processFieldVisibility()
      {
        const hideFields = this.hideColNames ? this.hideColNames.split(',') : []
        const disableFields = this.disableCols ? this.disableCols.split(',') : []

        for (const fld of this.internalFldList)
        {
          // 处理隐藏字段
          if (hideFields.includes(fld.colname))
          {
            fld.disporder = 0
          }

          // 处理禁用字段
          if (disableFields.includes(fld.colname))
          {
            fld.newedit = 0
            fld.editable = 0
          }
        }
      },

      /**
       * 获取可见字段
       * @param {Array} fldList 字段列表
       * @returns {Array} 可见字段列表
       */
      getVisibleFields(fldList)
      {         
        return fldList.filter(fld => fld.disporder !== 0)
      },

      /**
       * 判断字段是否启用
       * @param {Object} fld 字段对象
       * @returns {boolean} 是否启用
       */
      isFieldEnabled(fld)
      {
        if (!this.isViewMode())
        {
          if (fld.editable === 1)
          {
            return true
          }
          else if (this.isAddMode() && fld.newedit === 1)
          {
            return true
          }
        }

        return false
      },

      /**
       * 获取字段是否纵向布局
       * @param {Object} fld 字段对象
       * @returns {boolean} 是否纵向布局
       */
      getFieldPortrait(fld)
      {
        const invertFields = this.invertColNames ? this.invertColNames.split(',') : []
        const isInvert = invertFields.includes(fld.colname)
        return isInvert ? !this.portrait : this.portrait
      },

      /**
       * 获取字段提示信息
       * @param {Object} fld 字段对象
       * @returns {string} 提示信息
       */
      getFieldHint(fld)
      {
        return this.hintTextMap?.[fld.colname] || ''
      },

      /**
       * 获取字段项样式类
       * @param {Object} fld 字段对象
       * @returns {Object} 样式类对象
       */
      getFieldItemClass(fld)
      {
        return {
          'field-portrait': this.getFieldPortrait(fld),
          'field-disabled': !this.isFieldEnabled(fld),          
        }
      },

      // === 多列显示相关方法 ===

      /**
       * 判断是否应该使用多列显示
       * @param {Array} fldList 字段列表
       * @returns {boolean} 是否使用多列显示
       */
      shouldUseMultiColumn(fldList)
      {
        // 检查是否有字段配置了多列显示
        return fldList.some(fld => this.getFieldColumnCount(fld) > 1)
      },

      /**
       * 获取字段的列数配置
       * @param {Object} fld 字段对象
       * @returns {number} 列数
       */
      getFieldColumnCount(fld)
      {    
        // 优先从字段的params.rows获取列数配置
        if (fld.params && fld.params.rows && fld.params.rows < 1)
        {                       
          // 计算最大列数
          return Math.floor(1 / fld.params.rows)        
        }

        // 从全局colNum配置获取
        if (this.colNum && this.colNum > 1)
        {
          return this.colNum
        }

        // 从模板配置获取
        if (this.templateModel && this.templateModel.colNum && this.templateModel.colNum > 1)
        {
          return this.templateModel.colNum
        }

        return 1
      },

      /**
       * 获取多列布局的样式
       * @param {Array} fldList 字段列表
       * @returns {Object} 样式对象
       */
      getMultiColumnStyle(fldList)
      {
        const maxColumns = Math.max(...fldList.map(fld => this.getFieldColumnCount(fld)))
    
        if (maxColumns <= 1)
        {
          return {}
        }

        return {
          'grid-template-columns': `repeat(${maxColumns}, 1fr)`
        }
      },

      /**
       * 获取字段在多列布局中的网格位置
       * @param {Object} fld 字段对象
       * @param {number} index 字段索引
       * @returns {Object} 网格样式对象
       */
      getFieldGridStyle(fld, index)
      {
        const style = {}

        // 如果字段有特定的列配置
        if (fld.params && fld.params.rows)
        {
          // 查找字段在rows中的位置
          for (let rowIndex = 0; rowIndex < fld.params.rows.length; rowIndex++)
          {
            const row = fld.params.rows[rowIndex]
            if (Array.isArray(row))
            {
              const colIndex = row.findIndex(col => col === fld.colname)
              if (colIndex !== -1)
              {
                style['grid-row'] = rowIndex + 1
                style['grid-column'] = colIndex + 1
                break
              }
            }
          }
        }

        // 如果字段配置了跨列
        if (fld.params && fld.params.colspan && fld.params.colspan > 1)
        {
          style['grid-column-end'] = `span ${fld.params.colspan}`
        }

        // 如果字段配置了跨行
        if (fld.params && fld.params.rowspan && fld.params.rowspan > 1)
        {
          style['grid-row-end'] = `span ${fld.params.rowspan}`
        }

        return style
      },

      /**
       * 根据字段配置生成多列布局
       * @param {Array} fldList 字段列表
       * @returns {Array} 布局后的字段数组
       */
      generateMultiColumnLayout(fldList)
      {
        const layoutFields = []
              
        // 使用默认多列布局
        const columns = this.getFieldColumnCount(fldList[0]) 
        fldList.forEach((fld, index) =>
        {
          const row = Math.floor(index / columns)
          const col = index % columns

          const layoutFld = {
              ...fld,
              _layoutInfo: {
                row: row,
                col: col,
                gridRow: row + 1,
                gridColumn: col + 1
              }
          }
          layoutFields.push(layoutFld)
        })
      
        return layoutFields
      },

      /**
       * 根据布局信息生成网格样式
       * @param {Object} layoutInfo 布局信息
       * @returns {Object} 网格样式对象
       */
      getFieldGridStyleFromLayout(layoutInfo)
      {
        const style = {}

        // 注释掉强制网格位置的设置，让CSS Grid自动流布局处理
        // 这样可以确保字段平均分配宽度和正确的间距   
        // 如果需要跨列或跨行，可以保留这些设置
        if (layoutInfo.colspan && layoutInfo.colspan > 1)
        {
          style['grid-column-end'] = `span ${layoutInfo.colspan}`
        }

        if (layoutInfo.rowspan && layoutInfo.rowspan > 1)
        {
          style['grid-row-end'] = `span ${layoutInfo.rowspan}`
        }

        return style
      },

      // === cx_datafmt、cx_datavsl相关处理 ===
      /**
       * 解析字段params参数
       * @param   {Object}    fld    字段对象
       * @returns {Object}   解析后的params对象，如果无效则返回null 否则返回 {"format":"Currency","valid":"Min0","visual":"Emphasize"}
       */
        parseFieldParams(fld) 
        {
          if (!fld?.params) return null
          return typeof fld.params === 'string' ? JSON.parse(fld.params) : fld.params
        },
            
        /**
       * 处理所有字段的params参数 cx_datafmt、cx_datavsl 1、fld数据格式化配置 2、表单字段的颜色 3、配置验证规则用
       * @method
       */
        processFldAllFmtVsl() 
        {
          // 确保 internalFldList 已初始化
          if (!this.internalFldList || this.internalFldList.length === 0) 
          {
            return
          }

          this.internalFldList.forEach(fld => 
          {
            // 1. 初始化字段颜色
            fld.color = null
        
            // 2. 处理字段fld的params参数
            const params = this.parseFieldParams(fld)
            if (!params) return
        
            // 3. 处理字段的格式化、可视化和验证规则
            Object.entries(params).forEach(([type, value]) => 
            {
              this.processFldFmtVsl(type, value, fld)
            })   
          })                   
        },

      /**
       * 处理字段值的格式化、可视化和验证规则
       * @param   {String}    type      处理类型：format(格式化)、visual(可视化)、valid(验证)
       * @param   {String}    typeValue 处理参数
       * @param   {Object}    fld       字段对象
       */
      processFldFmtVsl(type, typeValue, fld) 
      {
        // 1. 根据类型处理字段值
        this.processFieldByType(type, typeValue, fld)

        // 2. 更新字段值到flds数组
        this.updateFieldInFlds(type, fld)
      },

      /**
       * 根据类型处理字段值
       * @param   {String}    type      处理类型
       * @param   {String}    typeValue 处理参数
       * @param   {Object}    fld       字段对象
       */
      processFieldByType(type, typeValue, fld) 
      {
        if (type === 'format') 
        {
          fld.value = uni.cxapp.Datafmt.format(fld.value, typeValue)
        } 
        else if (type === 'visual') 
        {
          fld.color = uni.cxapp.DataVsl.visual(fld.value, typeValue)
        } 
      },

      /**
       * 更新字段值到flds数组
       * @param   {String}    type      处理类型
       * @param   {Object}    fld       字段对象
       */
      updateFieldInFlds(type, fld) 
      {
        const item = this.internalFldList.find(item => item.id === fld.id)
        if (!item) return

        if (type === 'format') 
        {
          this.$set(item, 'value', fld.value)
        } 
        else if (type === 'visual') 
        {
          this.$set(item, 'color', fld.color)
        }
      }        
    }
}
